Change Factor Levels of Race, Income Percentile Groups, Bankruptcy, and Education
library(dplyr)
library(ggplot2)
library(plotly)
library(DT)
SCF$RACE <- factor(SCF$RACE,
levels = c("1", "2", "3", "5"),
labels = c("White\nNon-Hispanic", "Black", "Hispanic", "Other"))
SCF$INCCAT <- factor(ifelse(SCF$INCCAT <= 4, SCF$INCCAT, 5), levels = 1:5,
labels = c("0-19.9", "20-39.9", "40-59.9", "60-79.9", "80-100"))
SCF$NWCAT <- factor(ifelse(SCF$NWCAT <= 3, SCF$NWCAT, 4), levels = 1:4,
labels = c("0-24.9", "25-49.9", "50-74.9", "75-100"))
SCF$BNKRUPLAST5 <- factor(SCF$BNKRUPLAST5,
levels = c("0", "1"),
labels = c("No", "Yes"))
SCF$HHSEX <- factor(SCF$HHSEX,
levels = c("1", "2"),
labels = c("Male", "Female"))
SCF$MARRIED <- factor(SCF$MARRIED,
levels = c("1", "2"),
labels = c("Yes", "No"))
SCF$EDCL <- factor(SCF$EDCL,
levels = c("1", "2", "3", "4"),
labels = c("Less Than High School", "High School", "Some College", "College"))
1. Debt over time
a. Average Total Debt - Income Ratio
debtot <- SCF %>%
select(YEAR, DEBT2INC) %>%
group_by(YEAR) %>%
filter(DEBT2INC < 60000) %>%
summarise(avdebt2inc = round(mean(DEBT2INC), 2))
plot1a <- ggplot(debtot, aes(x = YEAR, y = avdebt2inc)) +
geom_line() +
geom_point(size = 3, color = "blue") +
ggtitle("Average Total Debt - Income Ratio (1989 - 2016)",
subtitle = "Data Source: Survey of Consumer Finances (SCF)") +
ylim(0.8, 1.6) +
xlim(1980, 2019) +
geom_text(aes(label = avdebt2inc),
hjust = 0.5, vjust = -0.5,
color = "red", size = 5) +
scale_x_continuous(breaks = debtot$YEAR) +
ylab("Total Debt - Income Ratio") +
xlab("Year")
Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing
scale.
plot1a

b. Average Student Loan and Total Debt - Bar Chart
edudebt1<- SCF %>%
select(YEAR, DEBT, EDN_INST) %>%
group_by(YEAR) %>%
summarise(avdebt = round(mean(DEBT), 2), avedu = round(mean(EDN_INST), 2))
plot1b <- ggplot(edudebt1, aes(x = YEAR, y = avdebt, fill = avedu)) +
geom_bar(stat = "identity") +
ggtitle("Average Student Loan and Total Debt (1989 - 2016)",
subtitle = "Data Source: Survey of Consumer Finances (SCF)") +
scale_x_continuous(breaks = edudebt1$YEAR) +
ylab("Average Total Debt") +
xlab("Year") +
scale_fill_continuous(name = "Average\nStudent\nLoan") +
scale_y_continuous(breaks = c(0, 50000, 100000, 150000, 200000, 250000, 300000, 350000),
labels = c("0", "50k", "100k", "150k", "200k", "250k", "300k", "350k"))
plot1b

c. Average Student Loan and Total Debt Ratio - Bar Chart
edudebt1<- SCF %>%
select(YEAR, DEBT, EDN_INST) %>%
group_by(YEAR) %>%
filter(DEBT > 0) %>%
summarise(edudeb = round(mean(EDN_INST / DEBT), 2))
plot1c <- ggplot(edudebt1, aes(x = YEAR, y = edudeb)) +
geom_bar(stat = "identity", fill = "royalblue4") +
ggtitle("Average Student Loan and Total Debt Ratio (1989 - 2016)",
subtitle = "Data Source: Survey of Consumer Finances (SCF)") +
ylim(0, 0.15) +
geom_text(aes(label = edudeb), vjust = -1,
color = "firebrick3", size = 5) +
scale_x_continuous(breaks = edudebt1$YEAR) +
ylab("Student Loan - Total Debt Ratio") +
xlab("Year")
plot1c

I would recommend plot1b. It is colorful and can show the increasing trend of higher education debt. The height of the bar shows the total amount of debt while the lighter color indicates higher average amount of education loan. Plot1b demonstrates the change of the amount of student loan and total debt that reveals the pattern that average student loan is increasing even though the total debt is decreasing since 2007 to 2016. At the same time, plot 1a shows the flucturating but, in general, increasing debt-income ratio and plot1c is also very helpful in showing the overall increasing trend of average education loan and total debt ratio. The label of plot1c accurately reflects the ratio of education loan and total debt.
2. Tell me who you are
a. Average Student Loan and Household Income Ratio vs. Number of Children and Marital Status
scfkids <- SCF %>%
select(YEAR, EDN_INST, INCOME, KIDS, MARRIED) %>%
filter(YEAR == 2016, INCOME > 0) %>%
mutate(eduinc1 = round(EDN_INST / INCOME, 2)) %>%
group_by(KIDS, MARRIED) %>%
summarise(eduk = round(mean(eduinc1), 2))
plot2a <- ggplot(scfkids, aes(x = KIDS, y = eduk, fill = MARRIED)) +
geom_bar(stat = "identity", position = "dodge") +
ggtitle("Average Student Loan and Household Income Ratio\nvs. Number of Children and Marital Status (2016)",
subtitle = "Data Source: Survey of Consumer Finances (SCF)") +
ylab("Student Loan - Income Ratio") +
xlab("Number of Children")
plot2a

b. Average Student Loan and Household Income Ratio vs. Number of Children and Gender
scfkg <- SCF %>%
select(YEAR, EDN_INST, INCOME, KIDS, HHSEX) %>%
filter(YEAR == 2016, INCOME > 0) %>%
mutate(eduinc1 = round(EDN_INST / INCOME, 2)) %>%
group_by(KIDS, HHSEX) %>%
summarise(eduk = round(mean(eduinc1), 2))
plot2b <- ggplot(scfkg, aes(x = KIDS, y = eduk, fill = HHSEX)) +
geom_bar(stat = "identity") +
ggtitle("Average Student Loan and Household Income Ratio\nvs. Number of Children and Gender (2016)",
subtitle = "Data Source: Survey of Consumer Finances (SCF)") +
ylab("Student Loan - Income Ratio") +
xlab("Number of Children") +
facet_grid(HHSEX ~ .) +
theme(legend.position = "none") +
scale_x_continuous(breaks = scfkg$KIDS)
plot2b

c. Average Student Loan and Household Income Ratio vs. Number of Children and Race
scfkg <- SCF %>%
select(YEAR, EDN_INST, INCOME, KIDS, RACE) %>%
filter(YEAR == 2016, INCOME > 0) %>%
mutate(eduinc1 = round(EDN_INST / INCOME, 2)) %>%
group_by(KIDS, RACE) %>%
summarise(eduk = round(mean(eduinc1), 2))
plot2c <- ggplot(scfkg, aes(x = KIDS, y = eduk, fill = RACE)) +
geom_bar(stat = "identity") +
ggtitle("Average Student Loan and Household Income Ratio\nvs. Number of Children and Race (2016)",
subtitle = "Data Source: Survey of Consumer Finances (SCF)") +
ylab("Student Loan - Income Ratio") +
xlab("Number of Children") +
facet_wrap(RACE ~ .) +
theme(legend.position = "none") +
scale_x_continuous(breaks = scfkg$KIDS)
plot2c

I use the number of children as the main independent variable and consider the influence of marital status, gender, and race as well. Overall, for married individuals, the more chidlren they have, the higher student loan - income ratio they have; but unmarried individuals tend to have higher student loan - income ratio than their married counterparts. Similar pattern is found in the comparison of male and female: for male, more chidlren indicates higher student loan - debt ratio but female tend to have higher student loan - debt ratio than their male counterparts. As for race, Black tend to have higher student loan- income ratio in general. There is no distinguishing pattern between number of children and race.
3. Wealth and Income Distribution
a. Student Loan - Income Ratio
scfwi <- SCF %>%
select(YEAR, EDN_INST, INCOME, INCCAT) %>%
filter(YEAR == 2016, INCOME > 0) %>%
mutate(eduinc = round(EDN_INST / INCOME, 2)) %>%
group_by(INCCAT) %>%
summarise(edu = round(mean(eduinc), 2))
plot3a <- ggplot(scfwi, aes(x = INCCAT, y = edu)) +
geom_bar(stat = "identity", fill = "royalblue4") +
ggtitle("Average Student Loan and Income Ratio vs. Income Percentile Groups (2016)",
subtitle = "Data Source: Survey of Consumer Finances (SCF)") +
ylab("Student Loan - Income Ratio") +
xlab("Income Percentile Groups") +
geom_text(aes(label = edu),
hjust = 0.5, vjust = -0.3,
color = "firebrick3", size = 4)
plot3a

b. Student Loan - Income Ratio vs. Income Percentile Groups & Race
scfp <- SCF %>%
select(YEAR, EDN_INST, INCOME, EDCL, INCCAT) %>%
filter(YEAR == 2016, INCOME > 0) %>%
mutate(eduinc = round(EDN_INST / INCOME, 2)) %>%
group_by(INCCAT, EDCL)
plot3b <- ggplot(scfp, aes(x = INCCAT, y = eduinc, color = EDCL)) +
geom_jitter() +
ggtitle("Average Student Loan and Household Income Ratio\nvs. Income Percentile Groups & Education (2016)",
subtitle = "Data Source: Survey of Consumer Finances (SCF)") +
ylab("Student Loan - Income Ratio") +
xlab("Income Percentile Groups") +
ylim(0, 5) +
facet_grid(EDCL ~ .) +
theme(legend.position = "none")
plot3b

c. Student Loan - Wealth Ratio vs. Net Worth Percentile Groups & Education
scfp <- SCF %>%
select(YEAR, EDN_INST, ASSET, EDCL, NWCAT) %>%
filter(YEAR == 2016, ASSET > 0) %>%
mutate(eduass = round(EDN_INST / ASSET, 2)) %>%
group_by(NWCAT, EDCL)
#filter(eduass > (mean(eduass)))
plot3c <- ggplot(scfp, aes(x = NWCAT, y = eduass, color = EDCL)) +
geom_jitter() +
ggtitle("Average Student Loan and Household Assets Ratio\nvs. Net Worth Percentile Groups & Education (2016)",
subtitle = "Data Source: Survey of Consumer Finances (SCF)") +
ylab("Student Loan - Asset Ratio") +
xlab("Net Worth Percentile Groups") +
facet_grid(EDCL ~ .) +
ylim(0, 5) +
theme(legend.position = "none")
plot3c

Plot3a well demonstrates that people of higher income percentile groups have lower student loan - income ratio. Plot3b further categorizes plot3a based on the education levels. It still shows the similar pattern of higher income, less indebted, It also shows that the more education received, the more indebted from education these people are, regardless of which income percentile group they belong to. Plot3c explores the relatioship between student loan - hosehold asset ratio and net worth percentile groups. Unlike the previous group that is based on income percentile groups, this plot shows an interesting and concentrated pattern of high indebtedness from educaiton of people who belong to the lowest net worth percentile group. The pattern that people of higher net worth percentil groups are less indebted from education is less distinguished. For both plot3b and plo3c, I only used a subset of student loan - income or asset ratio that is less than 5, removing more extreme cases, to show the pattern of the majority of people.
4. Going Broke
a. Student Loan - Debt Ratio and Bankruptcy or Foreclosure vs. Education
scfbf <- SCF %>%
select(YEAR, EDN_INST, DEBT, EDCL, BNKRUPLAST5, FORECLLAST5) %>%
filter(EDN_INST > 0, DEBT > 0) %>%
filter(BNKRUPLAST5 == "Yes" | FORECLLAST5 == 1) %>%
group_by(YEAR, EDCL) %>%
summarise(edubf = round(mean(EDN_INST / DEBT), 2))
plot4a <- ggplot(scfbf, aes(x = YEAR, y = edubf, color = EDCL)) +
geom_line(size = 1) +
ggtitle("Average Student Loan - Debt Ratio for Who Experienced\nBankruptcy or Foreclosure vs. Education (1998-2016)",
subtitle = "Data Source: Survey of Consumer Finances (SCF)") +
ylab("Student Loan - Debt Ratio") +
xlab("Year") +
facet_wrap(EDCL ~ .) +
theme(legend.position = "none") +
scale_x_continuous(breaks = scfbf$YEAR)
plot4a

b. Food - INCOME Ratio & Bankruptcy
scfbf <- SCF %>%
select(YEAR, BNKRUPLAST5, FOODHOME, FOODDELV, FOODAWAY, INCOME) %>%
filter(YEAR > 2003, INCOME > 0) %>%
group_by(YEAR, BNKRUPLAST5) %>%
summarise(food = round(mean((FOODHOME + FOODDELV + FOODAWAY) / INCOME), 6))
plot4b <- ggplot(scfbf, aes(x = YEAR, y = food, fill = BNKRUPLAST5)) +
geom_bar(stat = "identity", position = "dodge") +
ggtitle("Average Food Cost - Income Ratio & Bankruptcy (2004-2016)",
subtitle = "Data Source: Survey of Consumer Finances (SCF)") +
ylab("Food Cost - Income Ratio") +
xlab("Year") +
scale_x_continuous(breaks = scfbf$YEAR)
plot4b

c. Food - Asset Ratio & Bankruptcy
scfbf <- SCF %>%
select(YEAR, BNKRUPLAST5, FOODHOME, FOODDELV, FOODAWAY, ASSET) %>%
filter(YEAR > 2003, ASSET > 0) %>%
group_by(YEAR, BNKRUPLAST5) %>%
summarise(food = round(mean((FOODHOME + FOODDELV + FOODAWAY)/ASSET), 6))
plot4c <- ggplot(scfbf, aes(x = YEAR, y = food, fill = BNKRUPLAST5)) +
geom_bar(stat = "identity", position = "dodge") +
ggtitle("Average Food Cost - Asset Ratio & Bankruptcy (2004-2016)",
subtitle = "Data Source: Survey of Consumer Finances (SCF)") +
ylab("Food Cost - Asset Ratio") +
xlab("Year") +
scale_x_continuous(breaks = scfbf$YEAR)
plot4c

As plot 4a shown, average student loan and debt ratio for those who experienced bankruptcy or foreclosure varies among different educaiton levels. For people who has education of some college or more, student loan is playing a greater role in their bankruptcy or foreclosure. No clear pattern is found for people who has education of high school or less. Two clickbaity results are found in plot4b and 4c. Plot4b explores the relationship between the average food cost (including total amount spent on food at home, for delivery, and away from home) - income ratio and bankruptcy. People who experienced bankruptcy has a higher ratio of food cost and income than those who did not experience bankruptcy, which could be interpreted as people who spent more proportion of money on food are more likely to experience bankruptcy. Plot4c shows a completely different pattern. Those who have a higher food cost - asset ratio are less likely to have bankruptcy and their ratio is much higher than their counterparts who are bankrupted. It could have a misleading influence and unintended positive effect on food advertisement, which shows that spending more on food makes you less likely to be bankrupted.
5. Make two plots interactive
a.
(ggplotly(plot1b))
Adding interactivity to this plot enables readers to know the detail of this plot, like showing the amount of student loan and household debt, which compensates for the ambiguity of the differences among the colors.
b.
scfbf <- SCF %>%
select(YEAR, EDN_INST, DEBT, EDCL, BNKRUPLAST5, FORECLLAST5) %>%
filter(EDN_INST > 0, DEBT > 0) %>%
filter(BNKRUPLAST5 == "Yes" | FORECLLAST5 == 1) %>%
group_by(YEAR, EDCL) %>%
summarise(edubf = round(mean(EDN_INST / DEBT), 2))
plot5b <- ggplot(scfbf, aes(x = YEAR, y = edubf, color = EDCL)) +
geom_line(size = 1) +
ylab("Student Loan - Debt Ratio") +
xlab("Year") +
facet_wrap(EDCL ~ .) +
theme(legend.position = "none") +
scale_x_continuous(breaks = scfbf$YEAR)
plot5b <- ggplotly(plot5b)
plot5b[['x']][['layout']][['annotations']][[1]][['y']] <- -0.06
plot5b[['x']][['layout']][['annotations']][[2]][['x']] <- -0.06
plot5b
Adding interactivity to this plot enables readers to know the exact student loan - debt ratio of each year for different education levels. It makes the plot more informative and interactive.
6. Data Table
scfbf <- SCF %>%
select(YEAR, BNKRUPLAST5, FORECLLAST5, FOODDELV, FOODAWAY, DEBT, RACE) %>%
filter(YEAR > 2003, DEBT > 0) %>%
group_by(YEAR, BNKRUPLAST5, RACE) %>%
summarise(del = round(mean(FOODDELV/DEBT), 3)) %>%
filter(del > 0)
datatable(scfbf, colnames = c("Year", "Bankruptcy", "Race", "Food Delivery to Debt Ratio"),
filter = list(position = "top"))
This table is a subset of the dataset. It shows the amount spent on food delivery and total debt ratio among different race groups and bankruptcy status. It includes such information from all avaiable years from 2004 to 2016. The columns are well labeled. This table is helpful for readers to learn about the “extravagant” food consumption behaviors, food delivery, specifically. The ratio offers comparison with debt, which could be potentially educational to people who are interested in changing their food consumption behaviors.
LS0tDQp0aXRsZTogIkhvbWV3b3JrIDEgLSBTdHVkZW50IExvYW4iDQphdXRob3I6IFlpbmd0b25nIFpob3UNCmRhdGU6IDIwMjAtMDItMjYNCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0Kc2V0d2QoIn4vRGVza3RvcC9RTVNTIC0gQ1UvU3ByaW5nIDIwMjAvR1I1MDYzX0RhdGFWaXovY291cnNlX21hdGVyaWFscy9leGVyY2lzZXMvMDNfc3R1ZGVudF9sb2FucyIpDQpTQ0YgPC0gcmVhZC5jc3YoIn4vRGVza3RvcC9RTVNTIC0gQ1UvU3ByaW5nIDIwMjAvR1I1MDYzX0RhdGFWaXovY291cnNlX21hdGVyaWFscy9leGVyY2lzZXMvMDNfc3R1ZGVudF9sb2Fucy9zdXJ2ZXlfU0NGLnR4dCIpDQpgYGANCg0KDQojIyBDaGFuZ2UgRmFjdG9yIExldmVscyBvZiBSYWNlLCBJbmNvbWUgUGVyY2VudGlsZSBHcm91cHMsIEJhbmtydXB0Y3ksIGFuZCBFZHVjYXRpb24NCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShEVCkNClNDRiRSQUNFIDwtIGZhY3RvcihTQ0YkUkFDRSwgDQogICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIjEiLCAiMiIsICIzIiwgIjUiKSwgDQogICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIldoaXRlXG5Ob24tSGlzcGFuaWMiLCAiQmxhY2siLCAiSGlzcGFuaWMiLCAiT3RoZXIiKSkNClNDRiRJTkNDQVQgPC0gZmFjdG9yKGlmZWxzZShTQ0YkSU5DQ0FUIDw9IDQsIFNDRiRJTkNDQVQsIDUpLCBsZXZlbHMgPSAxOjUsDQogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCIwLTE5LjkiLCAiMjAtMzkuOSIsICI0MC01OS45IiwgIjYwLTc5LjkiLCAiODAtMTAwIikpDQpTQ0YkTldDQVQgPC0gZmFjdG9yKGlmZWxzZShTQ0YkTldDQVQgPD0gMywgU0NGJE5XQ0FULCA0KSwgbGV2ZWxzID0gMTo0LA0KICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiMC0yNC45IiwgIjI1LTQ5LjkiLCAiNTAtNzQuOSIsICI3NS0xMDAiKSkNClNDRiRCTktSVVBMQVNUNSA8LSBmYWN0b3IoU0NGJEJOS1JVUExBU1Q1LCANCiAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiMCIsICIxIiksIA0KICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJObyIsICJZZXMiKSkNClNDRiRISFNFWCA8LSBmYWN0b3IoU0NGJEhIU0VYLCANCiAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiMSIsICIyIiksIA0KICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJNYWxlIiwgIkZlbWFsZSIpKQ0KU0NGJE1BUlJJRUQgPC0gZmFjdG9yKFNDRiRNQVJSSUVELCANCiAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiMSIsICIyIiksIA0KICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJZZXMiLCAiTm8iKSkNClNDRiRFRENMIDwtIGZhY3RvcihTQ0YkRURDTCwgDQogICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIjEiLCAiMiIsICIzIiwgIjQiKSwgDQogICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkxlc3MgVGhhbiBIaWdoIFNjaG9vbCIsICJIaWdoIFNjaG9vbCIsICJTb21lIENvbGxlZ2UiLCAiQ29sbGVnZSIpKQ0KDQpgYGANCg0KDQojIDEuIERlYnQgb3ZlciB0aW1lDQojIyBhLiBBdmVyYWdlIFRvdGFsIERlYnQgLSBJbmNvbWUgUmF0aW8NCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0KZGVidG90IDwtIFNDRiAlPiUgDQogIHNlbGVjdChZRUFSLCBERUJUMklOQykgJT4lIA0KICBncm91cF9ieShZRUFSKSAlPiUgDQogIGZpbHRlcihERUJUMklOQyA8IDYwMDAwKSAlPiUgDQogIHN1bW1hcmlzZShhdmRlYnQyaW5jID0gcm91bmQobWVhbihERUJUMklOQyksIDIpKQ0KDQpwbG90MWEgPC0gZ2dwbG90KGRlYnRvdCwgYWVzKHggPSBZRUFSLCB5ID0gYXZkZWJ0MmluYykpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAzLCBjb2xvciA9ICJibHVlIikgKw0KICBnZ3RpdGxlKCJBdmVyYWdlIFRvdGFsIERlYnQgLSBJbmNvbWUgUmF0aW8gKDE5ODkgLSAyMDE2KSIsIA0KICAgICAgICAgIHN1YnRpdGxlID0gIkRhdGEgU291cmNlOiBTdXJ2ZXkgb2YgQ29uc3VtZXIgRmluYW5jZXMgKFNDRikiKSArDQogIHlsaW0oMC44LCAxLjYpICsNCiAgeGxpbSgxOTgwLCAyMDE5KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBhdmRlYnQyaW5jKSwgDQogICAgICAgICAgICBoanVzdCA9IDAuNSwgdmp1c3QgPSAtMC41LCANCiAgICAgICAgICAgIGNvbG9yID0gInJlZCIsIHNpemUgPSA1KSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBkZWJ0b3QkWUVBUikgKw0KICB5bGFiKCJUb3RhbCBEZWJ0IC0gSW5jb21lIFJhdGlvIikgKw0KICB4bGFiKCJZZWFyIikNCg0KcGxvdDFhDQpgYGANCg0KDQojIyBiLiBBdmVyYWdlIFN0dWRlbnQgTG9hbiBhbmQgVG90YWwgRGVidCAtIEJhciBDaGFydA0KYGBge3IsIHdhcm5pbmc9RkFMU0V9DQplZHVkZWJ0MTwtIFNDRiAlPiUgDQogIHNlbGVjdChZRUFSLCBERUJULCBFRE5fSU5TVCkgJT4lIA0KICBncm91cF9ieShZRUFSKSAlPiUgDQogIHN1bW1hcmlzZShhdmRlYnQgPSByb3VuZChtZWFuKERFQlQpLCAyKSwgYXZlZHUgPSByb3VuZChtZWFuKEVETl9JTlNUKSwgMikpDQoNCnBsb3QxYiA8LSBnZ3Bsb3QoZWR1ZGVidDEsIGFlcyh4ID0gWUVBUiwgeSA9IGF2ZGVidCwgZmlsbCA9IGF2ZWR1KSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBnZ3RpdGxlKCJBdmVyYWdlIFN0dWRlbnQgTG9hbiBhbmQgVG90YWwgRGVidCAoMTk4OSAtIDIwMTYpIiwgDQogICAgICAgICAgc3VidGl0bGUgPSAiRGF0YSBTb3VyY2U6IFN1cnZleSBvZiBDb25zdW1lciBGaW5hbmNlcyAoU0NGKSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGVkdWRlYnQxJFlFQVIpICsNCiAgeWxhYigiQXZlcmFnZSBUb3RhbCBEZWJ0IikgKw0KICB4bGFiKCJZZWFyIikgKw0KICBzY2FsZV9maWxsX2NvbnRpbnVvdXMobmFtZSA9ICJBdmVyYWdlXG5TdHVkZW50XG5Mb2FuIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLCA1MDAwMCwgMTAwMDAwLCAxNTAwMDAsIDIwMDAwMCwgMjUwMDAwLCAzMDAwMDAsIDM1MDAwMCksIA0KICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiMCIsICI1MGsiLCAiMTAwayIsICIxNTBrIiwgIjIwMGsiLCAiMjUwayIsICIzMDBrIiwgIjM1MGsiKSkNCg0KcGxvdDFiDQpgYGANCg0KDQojIyBjLiBBdmVyYWdlIFN0dWRlbnQgTG9hbiBhbmQgVG90YWwgRGVidCBSYXRpbyAtIEJhciBDaGFydA0KYGBge3IsIHdhcm5pbmc9RkFMU0V9DQplZHVkZWJ0MTwtIFNDRiAlPiUgDQogIHNlbGVjdChZRUFSLCBERUJULCBFRE5fSU5TVCkgJT4lIA0KICBncm91cF9ieShZRUFSKSAlPiUgDQogIGZpbHRlcihERUJUID4gMCkgJT4lIA0KICBzdW1tYXJpc2UoZWR1ZGViID0gcm91bmQobWVhbihFRE5fSU5TVCAvIERFQlQpLCAyKSkNCg0KcGxvdDFjIDwtIGdncGxvdChlZHVkZWJ0MSwgYWVzKHggPSBZRUFSLCB5ID0gZWR1ZGViKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICJyb3lhbGJsdWU0IikgKw0KICBnZ3RpdGxlKCJBdmVyYWdlIFN0dWRlbnQgTG9hbiBhbmQgVG90YWwgRGVidCBSYXRpbyAoMTk4OSAtIDIwMTYpIiwgDQogICAgICAgICAgc3VidGl0bGUgPSAiRGF0YSBTb3VyY2U6IFN1cnZleSBvZiBDb25zdW1lciBGaW5hbmNlcyAoU0NGKSIpICsNCiAgeWxpbSgwLCAwLjE1KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBlZHVkZWIpLCB2anVzdCA9IC0xLCANCiAgICAgICAgICAgIGNvbG9yID0gImZpcmVicmljazMiLCBzaXplID0gNSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gZWR1ZGVidDEkWUVBUikgKw0KICB5bGFiKCJTdHVkZW50IExvYW4gLSBUb3RhbCBEZWJ0IFJhdGlvIikgKw0KICB4bGFiKCJZZWFyIikNCg0KcGxvdDFjDQpgYGANCg0KDQpJIHdvdWxkIHJlY29tbWVuZCBwbG90MWIuIEl0IGlzIGNvbG9yZnVsIGFuZCBjYW4gc2hvdyB0aGUgaW5jcmVhc2luZyB0cmVuZCBvZiBoaWdoZXIgZWR1Y2F0aW9uIGRlYnQuIFRoZSBoZWlnaHQgb2YgdGhlIGJhciBzaG93cyB0aGUgdG90YWwgYW1vdW50IG9mIGRlYnQgd2hpbGUgdGhlIGxpZ2h0ZXIgY29sb3IgaW5kaWNhdGVzIGhpZ2hlciBhdmVyYWdlIGFtb3VudCBvZiBlZHVjYXRpb24gbG9hbi4gUGxvdDFiIGRlbW9uc3RyYXRlcyB0aGUgY2hhbmdlIG9mIHRoZSBhbW91bnQgb2Ygc3R1ZGVudCBsb2FuIGFuZCB0b3RhbCBkZWJ0IHRoYXQgcmV2ZWFscyB0aGUgcGF0dGVybiB0aGF0IGF2ZXJhZ2Ugc3R1ZGVudCBsb2FuIGlzIGluY3JlYXNpbmcgZXZlbiB0aG91Z2ggdGhlIHRvdGFsIGRlYnQgaXMgZGVjcmVhc2luZyBzaW5jZSAyMDA3IHRvIDIwMTYuIEF0IHRoZSBzYW1lIHRpbWUsIHBsb3QgMWEgc2hvd3MgdGhlIGZsdWN0dXJhdGluZyBidXQsIGluIGdlbmVyYWwsIGluY3JlYXNpbmcgZGVidC1pbmNvbWUgcmF0aW8gYW5kIHBsb3QxYyBpcyBhbHNvIHZlcnkgaGVscGZ1bCBpbiBzaG93aW5nIHRoZSBvdmVyYWxsIGluY3JlYXNpbmcgdHJlbmQgb2YgYXZlcmFnZSBlZHVjYXRpb24gbG9hbiBhbmQgdG90YWwgZGVidCByYXRpby4gVGhlIGxhYmVsIG9mIHBsb3QxYyBhY2N1cmF0ZWx5IHJlZmxlY3RzIHRoZSByYXRpbyBvZiBlZHVjYXRpb24gbG9hbiBhbmQgdG90YWwgZGVidC4NCg0KDQojIDIuIFRlbGwgbWUgd2hvIHlvdSBhcmUNCiMjIGEuIEF2ZXJhZ2UgU3R1ZGVudCBMb2FuIGFuZCBIb3VzZWhvbGQgSW5jb21lIFJhdGlvIHZzLiBOdW1iZXIgb2YgQ2hpbGRyZW4gYW5kIE1hcml0YWwgU3RhdHVzDQpgYGB7ciwgd2FybmluZz1GQUxTRX0NCnNjZmtpZHMgPC0gU0NGICU+JSANCiAgc2VsZWN0KFlFQVIsIEVETl9JTlNULCBJTkNPTUUsIEtJRFMsIE1BUlJJRUQpICU+JSANCiAgZmlsdGVyKFlFQVIgPT0gMjAxNiwgSU5DT01FID4gMCkgJT4lIA0KICBtdXRhdGUoZWR1aW5jMSA9IHJvdW5kKEVETl9JTlNUIC8gSU5DT01FLCAyKSkgJT4lIA0KICBncm91cF9ieShLSURTLCBNQVJSSUVEKSAlPiUgDQogIHN1bW1hcmlzZShlZHVrID0gcm91bmQobWVhbihlZHVpbmMxKSwgMikpDQoNCnBsb3QyYSA8LSBnZ3Bsb3Qoc2Nma2lkcywgYWVzKHggPSBLSURTLCB5ID0gZWR1aywgZmlsbCA9IE1BUlJJRUQpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgZ2d0aXRsZSgiQXZlcmFnZSBTdHVkZW50IExvYW4gYW5kIEhvdXNlaG9sZCBJbmNvbWUgUmF0aW9cbnZzLiBOdW1iZXIgb2YgQ2hpbGRyZW4gYW5kIE1hcml0YWwgU3RhdHVzICgyMDE2KSIsIA0KICAgICAgICAgIHN1YnRpdGxlID0gIkRhdGEgU291cmNlOiBTdXJ2ZXkgb2YgQ29uc3VtZXIgRmluYW5jZXMgKFNDRikiKSArDQogIHlsYWIoIlN0dWRlbnQgTG9hbiAtIEluY29tZSBSYXRpbyIpICsNCiAgeGxhYigiTnVtYmVyIG9mIENoaWxkcmVuIikNCg0KcGxvdDJhDQpgYGANCg0KDQojIyBiLiBBdmVyYWdlIFN0dWRlbnQgTG9hbiBhbmQgSG91c2Vob2xkIEluY29tZSBSYXRpbyB2cy4gTnVtYmVyIG9mIENoaWxkcmVuIGFuZCBHZW5kZXINCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0Kc2Nma2cgPC0gU0NGICU+JSANCiAgc2VsZWN0KFlFQVIsIEVETl9JTlNULCBJTkNPTUUsIEtJRFMsIEhIU0VYKSAlPiUgDQogIGZpbHRlcihZRUFSID09IDIwMTYsIElOQ09NRSA+IDApICU+JSANCiAgbXV0YXRlKGVkdWluYzEgPSByb3VuZChFRE5fSU5TVCAvIElOQ09NRSwgMikpICU+JSANCiAgZ3JvdXBfYnkoS0lEUywgSEhTRVgpICU+JSANCiAgc3VtbWFyaXNlKGVkdWsgPSByb3VuZChtZWFuKGVkdWluYzEpLCAyKSkNCg0KcGxvdDJiIDwtIGdncGxvdChzY2ZrZywgYWVzKHggPSBLSURTLCB5ID0gZWR1aywgZmlsbCA9IEhIU0VYKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBnZ3RpdGxlKCJBdmVyYWdlIFN0dWRlbnQgTG9hbiBhbmQgSG91c2Vob2xkIEluY29tZSBSYXRpb1xudnMuIE51bWJlciBvZiBDaGlsZHJlbiBhbmQgR2VuZGVyICgyMDE2KSIsIA0KICAgICAgICAgIHN1YnRpdGxlID0gIkRhdGEgU291cmNlOiBTdXJ2ZXkgb2YgQ29uc3VtZXIgRmluYW5jZXMgKFNDRikiKSArDQogIHlsYWIoIlN0dWRlbnQgTG9hbiAtIEluY29tZSBSYXRpbyIpICsNCiAgeGxhYigiTnVtYmVyIG9mIENoaWxkcmVuIikgKw0KICBmYWNldF9ncmlkKEhIU0VYIH4gLikgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNjZmtnJEtJRFMpDQoNCnBsb3QyYg0KYGBgDQoNCg0KIyMgYy4gQXZlcmFnZSBTdHVkZW50IExvYW4gYW5kIEhvdXNlaG9sZCBJbmNvbWUgUmF0aW8gdnMuIE51bWJlciBvZiBDaGlsZHJlbiBhbmQgUmFjZQ0KYGBge3IsIHdhcm5pbmc9RkFMU0V9DQpzY2ZrZyA8LSBTQ0YgJT4lIA0KICBzZWxlY3QoWUVBUiwgRUROX0lOU1QsIElOQ09NRSwgS0lEUywgUkFDRSkgJT4lIA0KICBmaWx0ZXIoWUVBUiA9PSAyMDE2LCBJTkNPTUUgPiAwKSAlPiUgDQogIG11dGF0ZShlZHVpbmMxID0gcm91bmQoRUROX0lOU1QgLyBJTkNPTUUsIDIpKSAlPiUgDQogIGdyb3VwX2J5KEtJRFMsIFJBQ0UpICU+JSANCiAgc3VtbWFyaXNlKGVkdWsgPSByb3VuZChtZWFuKGVkdWluYzEpLCAyKSkNCg0KcGxvdDJjIDwtIGdncGxvdChzY2ZrZywgYWVzKHggPSBLSURTLCB5ID0gZWR1aywgZmlsbCA9IFJBQ0UpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIGdndGl0bGUoIkF2ZXJhZ2UgU3R1ZGVudCBMb2FuIGFuZCBIb3VzZWhvbGQgSW5jb21lIFJhdGlvXG52cy4gTnVtYmVyIG9mIENoaWxkcmVuIGFuZCBSYWNlICgyMDE2KSIsIA0KICAgICAgICAgIHN1YnRpdGxlID0gIkRhdGEgU291cmNlOiBTdXJ2ZXkgb2YgQ29uc3VtZXIgRmluYW5jZXMgKFNDRikiKSArDQogIHlsYWIoIlN0dWRlbnQgTG9hbiAtIEluY29tZSBSYXRpbyIpICsNCiAgeGxhYigiTnVtYmVyIG9mIENoaWxkcmVuIikgKw0KICBmYWNldF93cmFwKFJBQ0UgfiAuKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2Nma2ckS0lEUykNCg0KcGxvdDJjDQpgYGANCg0KDQpJIHVzZSB0aGUgbnVtYmVyIG9mIGNoaWxkcmVuIGFzIHRoZSBtYWluIGluZGVwZW5kZW50IHZhcmlhYmxlIGFuZCBjb25zaWRlciB0aGUgaW5mbHVlbmNlIG9mIG1hcml0YWwgc3RhdHVzLCBnZW5kZXIsIGFuZCByYWNlIGFzIHdlbGwuIE92ZXJhbGwsIGZvciBtYXJyaWVkIGluZGl2aWR1YWxzLCB0aGUgbW9yZSBjaGlkbHJlbiB0aGV5IGhhdmUsIHRoZSBoaWdoZXIgc3R1ZGVudCBsb2FuIC0gaW5jb21lIHJhdGlvIHRoZXkgaGF2ZTsgYnV0IHVubWFycmllZCBpbmRpdmlkdWFscyB0ZW5kIHRvIGhhdmUgaGlnaGVyIHN0dWRlbnQgbG9hbiAtIGluY29tZSByYXRpbyB0aGFuIHRoZWlyIG1hcnJpZWQgY291bnRlcnBhcnRzLiBTaW1pbGFyIHBhdHRlcm4gaXMgZm91bmQgaW4gdGhlIGNvbXBhcmlzb24gb2YgbWFsZSBhbmQgZmVtYWxlOiBmb3IgbWFsZSwgbW9yZSBjaGlkbHJlbiBpbmRpY2F0ZXMgaGlnaGVyIHN0dWRlbnQgbG9hbiAtIGRlYnQgcmF0aW8gYnV0IGZlbWFsZSB0ZW5kIHRvIGhhdmUgaGlnaGVyIHN0dWRlbnQgbG9hbiAtIGRlYnQgcmF0aW8gdGhhbiB0aGVpciBtYWxlIGNvdW50ZXJwYXJ0cy4gQXMgZm9yIHJhY2UsIEJsYWNrIHRlbmQgdG8gaGF2ZSBoaWdoZXIgc3R1ZGVudCBsb2FuLSBpbmNvbWUgcmF0aW8gaW4gZ2VuZXJhbC4gVGhlcmUgaXMgbm8gZGlzdGluZ3Vpc2hpbmcgcGF0dGVybiBiZXR3ZWVuIG51bWJlciBvZiBjaGlsZHJlbiBhbmQgcmFjZS4NCg0KDQojIDMuIFdlYWx0aCBhbmQgSW5jb21lIERpc3RyaWJ1dGlvbg0KIyMgYS4gU3R1ZGVudCBMb2FuIC0gSW5jb21lIFJhdGlvDQpgYGB7ciwgd2FybmluZz1GQUxTRX0NCnNjZndpIDwtIFNDRiAlPiUgDQogIHNlbGVjdChZRUFSLCBFRE5fSU5TVCwgSU5DT01FLCBJTkNDQVQpICU+JSANCiAgZmlsdGVyKFlFQVIgPT0gMjAxNiwgSU5DT01FID4gMCkgJT4lIA0KICBtdXRhdGUoZWR1aW5jID0gcm91bmQoRUROX0lOU1QgLyBJTkNPTUUsIDIpKSAlPiUgDQogIGdyb3VwX2J5KElOQ0NBVCkgJT4lIA0KICBzdW1tYXJpc2UoZWR1ID0gcm91bmQobWVhbihlZHVpbmMpLCAyKSkNCg0KcGxvdDNhIDwtIGdncGxvdChzY2Z3aSwgYWVzKHggPSBJTkNDQVQsIHkgPSBlZHUpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gInJveWFsYmx1ZTQiKSArDQogIGdndGl0bGUoIkF2ZXJhZ2UgU3R1ZGVudCBMb2FuIGFuZCBJbmNvbWUgUmF0aW8gdnMuIEluY29tZSBQZXJjZW50aWxlIEdyb3VwcyAoMjAxNikiLCANCiAgICAgICAgICBzdWJ0aXRsZSA9ICJEYXRhIFNvdXJjZTogU3VydmV5IG9mIENvbnN1bWVyIEZpbmFuY2VzIChTQ0YpIikgKw0KICB5bGFiKCJTdHVkZW50IExvYW4gLSBJbmNvbWUgUmF0aW8iKSArDQogIHhsYWIoIkluY29tZSBQZXJjZW50aWxlIEdyb3VwcyIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGVkdSksIA0KICAgICAgICAgICAgaGp1c3QgPSAwLjUsIHZqdXN0ID0gLTAuMywgDQogICAgICAgICAgICBjb2xvciA9ICJmaXJlYnJpY2szIiwgc2l6ZSA9IDQpDQoNCnBsb3QzYQ0KYGBgDQoNCg0KIyMgYi4gU3R1ZGVudCBMb2FuIC0gSW5jb21lIFJhdGlvIHZzLiBJbmNvbWUgUGVyY2VudGlsZSBHcm91cHMgJiBSYWNlDQpgYGB7ciwgd2FybmluZz1GQUxTRX0NCnNjZnAgPC0gU0NGICU+JSANCiAgc2VsZWN0KFlFQVIsIEVETl9JTlNULCBJTkNPTUUsIEVEQ0wsIElOQ0NBVCkgJT4lIA0KICBmaWx0ZXIoWUVBUiA9PSAyMDE2LCBJTkNPTUUgPiAwKSAlPiUgDQogIG11dGF0ZShlZHVpbmMgPSByb3VuZChFRE5fSU5TVCAvIElOQ09NRSwgMikpICU+JQ0KICBncm91cF9ieShJTkNDQVQsIEVEQ0wpDQoNCnBsb3QzYiA8LSBnZ3Bsb3Qoc2NmcCwgYWVzKHggPSBJTkNDQVQsIHkgPSBlZHVpbmMsIGNvbG9yID0gRURDTCkpICsNCiAgZ2VvbV9qaXR0ZXIoKSArDQogIGdndGl0bGUoIkF2ZXJhZ2UgU3R1ZGVudCBMb2FuIGFuZCBIb3VzZWhvbGQgSW5jb21lIFJhdGlvXG52cy4gSW5jb21lIFBlcmNlbnRpbGUgR3JvdXBzICYgRWR1Y2F0aW9uICgyMDE2KSIsIA0KICAgICAgICAgIHN1YnRpdGxlID0gIkRhdGEgU291cmNlOiBTdXJ2ZXkgb2YgQ29uc3VtZXIgRmluYW5jZXMgKFNDRikiKSArDQogIHlsYWIoIlN0dWRlbnQgTG9hbiAtIEluY29tZSBSYXRpbyIpICsNCiAgeGxhYigiSW5jb21lIFBlcmNlbnRpbGUgR3JvdXBzIikgKw0KICB5bGltKDAsIDUpICsNCiAgZmFjZXRfZ3JpZChFRENMIH4gLikgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNCnBsb3QzYg0KYGBgDQoNCg0KIyMgYy4gU3R1ZGVudCBMb2FuIC0gV2VhbHRoIFJhdGlvIHZzLiBOZXQgV29ydGggUGVyY2VudGlsZSBHcm91cHMgJiBFZHVjYXRpb24NCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0Kc2NmcCA8LSBTQ0YgJT4lIA0KICBzZWxlY3QoWUVBUiwgRUROX0lOU1QsIEFTU0VULCBFRENMLCBOV0NBVCkgJT4lIA0KICBmaWx0ZXIoWUVBUiA9PSAyMDE2LCBBU1NFVCA+IDApICU+JSANCiAgbXV0YXRlKGVkdWFzcyA9IHJvdW5kKEVETl9JTlNUIC8gQVNTRVQsIDIpKSAlPiUNCiAgZ3JvdXBfYnkoTldDQVQsIEVEQ0wpDQogICNmaWx0ZXIoZWR1YXNzID4gKG1lYW4oZWR1YXNzKSkpDQoNCnBsb3QzYyA8LSBnZ3Bsb3Qoc2NmcCwgYWVzKHggPSBOV0NBVCwgeSA9IGVkdWFzcywgY29sb3IgPSBFRENMKSkgKw0KICBnZW9tX2ppdHRlcigpICsNCiAgZ2d0aXRsZSgiQXZlcmFnZSBTdHVkZW50IExvYW4gYW5kIEhvdXNlaG9sZCBBc3NldHMgUmF0aW9cbnZzLiBOZXQgV29ydGggUGVyY2VudGlsZSBHcm91cHMgJiBFZHVjYXRpb24gKDIwMTYpIiwgDQogICAgICAgICAgc3VidGl0bGUgPSAiRGF0YSBTb3VyY2U6IFN1cnZleSBvZiBDb25zdW1lciBGaW5hbmNlcyAoU0NGKSIpICsNCiAgeWxhYigiU3R1ZGVudCBMb2FuIC0gQXNzZXQgUmF0aW8iKSArDQogIHhsYWIoIk5ldCBXb3J0aCBQZXJjZW50aWxlIEdyb3VwcyIpICsNCiAgZmFjZXRfZ3JpZChFRENMIH4gLikgKw0KICB5bGltKDAsIDUpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KDQpwbG90M2MNCmBgYA0KDQoNClBsb3QzYSB3ZWxsIGRlbW9uc3RyYXRlcyB0aGF0IHBlb3BsZSBvZiBoaWdoZXIgaW5jb21lIHBlcmNlbnRpbGUgZ3JvdXBzIGhhdmUgbG93ZXIgc3R1ZGVudCBsb2FuIC0gaW5jb21lIHJhdGlvLiBQbG90M2IgZnVydGhlciBjYXRlZ29yaXplcyBwbG90M2EgYmFzZWQgb24gdGhlIGVkdWNhdGlvbiBsZXZlbHMuIEl0IHN0aWxsIHNob3dzIHRoZSAgc2ltaWxhciBwYXR0ZXJuIG9mIGhpZ2hlciBpbmNvbWUsIGxlc3MgaW5kZWJ0ZWQsIEl0IGFsc28gc2hvd3MgdGhhdCB0aGUgbW9yZSBlZHVjYXRpb24gcmVjZWl2ZWQsIHRoZSBtb3JlIGluZGVidGVkIGZyb20gZWR1Y2F0aW9uIHRoZXNlIHBlb3BsZSBhcmUsIHJlZ2FyZGxlc3Mgb2Ygd2hpY2ggaW5jb21lIHBlcmNlbnRpbGUgZ3JvdXAgdGhleSBiZWxvbmcgdG8uIFBsb3QzYyBleHBsb3JlcyB0aGUgcmVsYXRpb3NoaXAgYmV0d2VlbiBzdHVkZW50IGxvYW4gLSBob3NlaG9sZCBhc3NldCByYXRpbyBhbmQgbmV0IHdvcnRoIHBlcmNlbnRpbGUgZ3JvdXBzLiBVbmxpa2UgdGhlIHByZXZpb3VzIGdyb3VwIHRoYXQgaXMgYmFzZWQgb24gaW5jb21lIHBlcmNlbnRpbGUgZ3JvdXBzLCB0aGlzIHBsb3Qgc2hvd3MgYW4gaW50ZXJlc3RpbmcgYW5kIGNvbmNlbnRyYXRlZCBwYXR0ZXJuIG9mIGhpZ2ggaW5kZWJ0ZWRuZXNzIGZyb20gZWR1Y2FpdG9uIG9mIHBlb3BsZSB3aG8gYmVsb25nIHRvIHRoZSBsb3dlc3QgbmV0IHdvcnRoIHBlcmNlbnRpbGUgZ3JvdXAuIFRoZSBwYXR0ZXJuIHRoYXQgcGVvcGxlIG9mIGhpZ2hlciBuZXQgd29ydGggcGVyY2VudGlsIGdyb3VwcyBhcmUgbGVzcyBpbmRlYnRlZCBmcm9tIGVkdWNhdGlvbiBpcyBsZXNzIGRpc3Rpbmd1aXNoZWQuIEZvciBib3RoIHBsb3QzYiBhbmQgcGxvM2MsIEkgb25seSB1c2VkIGEgc3Vic2V0IG9mIHN0dWRlbnQgbG9hbiAtIGluY29tZSBvciBhc3NldCByYXRpbyB0aGF0IGlzIGxlc3MgdGhhbiA1LCByZW1vdmluZyBtb3JlIGV4dHJlbWUgY2FzZXMsIHRvIHNob3cgdGhlIHBhdHRlcm4gb2YgdGhlIG1ham9yaXR5IG9mIHBlb3BsZS4NCg0KDQojIDQuIEdvaW5nIEJyb2tlDQojIyBhLiBTdHVkZW50IExvYW4gLSBEZWJ0IFJhdGlvIGFuZCBCYW5rcnVwdGN5IG9yIEZvcmVjbG9zdXJlIHZzLiBFZHVjYXRpb24NCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0Kc2NmYmYgPC0gU0NGICU+JSANCiAgc2VsZWN0KFlFQVIsIEVETl9JTlNULCBERUJULCBFRENMLCBCTktSVVBMQVNUNSwgRk9SRUNMTEFTVDUpICU+JSANCiAgZmlsdGVyKEVETl9JTlNUID4gMCwgREVCVCA+IDApICU+JSANCiAgZmlsdGVyKEJOS1JVUExBU1Q1ID09ICJZZXMiIHwgRk9SRUNMTEFTVDUgPT0gMSkgJT4lIA0KICBncm91cF9ieShZRUFSLCBFRENMKSAlPiUgDQogIHN1bW1hcmlzZShlZHViZiA9IHJvdW5kKG1lYW4oRUROX0lOU1QgLyBERUJUKSwgMikpDQoNCnBsb3Q0YSA8LSBnZ3Bsb3Qoc2NmYmYsIGFlcyh4ID0gWUVBUiwgeSA9IGVkdWJmLCBjb2xvciA9IEVEQ0wpKSArDQogIGdlb21fbGluZShzaXplID0gMSkgKw0KICBnZ3RpdGxlKCJBdmVyYWdlIFN0dWRlbnQgTG9hbiAtIERlYnQgUmF0aW8gZm9yIFdobyBFeHBlcmllbmNlZFxuQmFua3J1cHRjeSBvciBGb3JlY2xvc3VyZSB2cy4gRWR1Y2F0aW9uICgxOTk4LTIwMTYpIiwgDQogICAgICAgICAgc3VidGl0bGUgPSAiRGF0YSBTb3VyY2U6IFN1cnZleSBvZiBDb25zdW1lciBGaW5hbmNlcyAoU0NGKSIpICsNCiAgeWxhYigiU3R1ZGVudCBMb2FuIC0gRGVidCBSYXRpbyIpICsNCiAgeGxhYigiWWVhciIpICsNCiAgZmFjZXRfd3JhcChFRENMIH4gLikgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNjZmJmJFlFQVIpDQoNCnBsb3Q0YQ0KYGBgDQoNCg0KIyMgYi4gRm9vZCAtIElOQ09NRSBSYXRpbyAmIEJhbmtydXB0Y3kNCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0Kc2NmYmYgPC0gU0NGICU+JSANCiAgc2VsZWN0KFlFQVIsIEJOS1JVUExBU1Q1LCBGT09ESE9NRSwgRk9PRERFTFYsIEZPT0RBV0FZLCBJTkNPTUUpICU+JSANCiAgZmlsdGVyKFlFQVIgPiAyMDAzLCBJTkNPTUUgPiAwKSAlPiUgDQogIGdyb3VwX2J5KFlFQVIsIEJOS1JVUExBU1Q1KSAlPiUgDQogIHN1bW1hcmlzZShmb29kID0gcm91bmQobWVhbigoRk9PREhPTUUgKyBGT09EREVMViArIEZPT0RBV0FZKSAvIElOQ09NRSksIDYpKQ0KDQpwbG90NGIgPC0gZ2dwbG90KHNjZmJmLCBhZXMoeCA9IFlFQVIsIHkgPSBmb29kLCBmaWxsID0gQk5LUlVQTEFTVDUpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgZ2d0aXRsZSgiQXZlcmFnZSBGb29kIENvc3QgLSBJbmNvbWUgUmF0aW8gJiBCYW5rcnVwdGN5ICgyMDA0LTIwMTYpIiwgDQogICAgICAgICAgc3VidGl0bGUgPSAiRGF0YSBTb3VyY2U6IFN1cnZleSBvZiBDb25zdW1lciBGaW5hbmNlcyAoU0NGKSIpICsNCiAgeWxhYigiRm9vZCBDb3N0IC0gSW5jb21lIFJhdGlvIikgKw0KICB4bGFiKCJZZWFyIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2NmYmYkWUVBUikNCg0KcGxvdDRiDQpgYGANCg0KDQojIyBjLiBGb29kIC0gQXNzZXQgUmF0aW8gJiBCYW5rcnVwdGN5DQpgYGB7ciwgd2FybmluZz1GQUxTRX0NCnNjZmJmIDwtIFNDRiAlPiUgDQogIHNlbGVjdChZRUFSLCBCTktSVVBMQVNUNSwgRk9PREhPTUUsIEZPT0RERUxWLCBGT09EQVdBWSwgQVNTRVQpICU+JSANCiAgZmlsdGVyKFlFQVIgPiAyMDAzLCBBU1NFVCA+IDApICU+JSANCiAgZ3JvdXBfYnkoWUVBUiwgQk5LUlVQTEFTVDUpICU+JSANCiAgc3VtbWFyaXNlKGZvb2QgPSByb3VuZChtZWFuKChGT09ESE9NRSArIEZPT0RERUxWICsgRk9PREFXQVkpL0FTU0VUKSwgNikpDQoNCnBsb3Q0YyA8LSBnZ3Bsb3Qoc2NmYmYsIGFlcyh4ID0gWUVBUiwgeSA9IGZvb2QsIGZpbGwgPSBCTktSVVBMQVNUNSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBnZ3RpdGxlKCJBdmVyYWdlIEZvb2QgQ29zdCAtIEFzc2V0IFJhdGlvICYgQmFua3J1cHRjeSAoMjAwNC0yMDE2KSIsIA0KICAgICAgICAgIHN1YnRpdGxlID0gIkRhdGEgU291cmNlOiBTdXJ2ZXkgb2YgQ29uc3VtZXIgRmluYW5jZXMgKFNDRikiKSArDQogIHlsYWIoIkZvb2QgQ29zdCAtIEFzc2V0IFJhdGlvIikgKw0KICB4bGFiKCJZZWFyIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2NmYmYkWUVBUikNCg0KcGxvdDRjDQpgYGANCg0KDQpBcyBwbG90IDRhIHNob3duLCBhdmVyYWdlIHN0dWRlbnQgbG9hbiBhbmQgZGVidCByYXRpbyBmb3IgdGhvc2Ugd2hvIGV4cGVyaWVuY2VkIGJhbmtydXB0Y3kgb3IgZm9yZWNsb3N1cmUgdmFyaWVzIGFtb25nIGRpZmZlcmVudCBlZHVjYWl0b24gbGV2ZWxzLiBGb3IgcGVvcGxlIHdobyBoYXMgZWR1Y2F0aW9uIG9mIHNvbWUgY29sbGVnZSBvciBtb3JlLCBzdHVkZW50IGxvYW4gaXMgcGxheWluZyBhIGdyZWF0ZXIgcm9sZSBpbiB0aGVpciBiYW5rcnVwdGN5IG9yIGZvcmVjbG9zdXJlLiBObyBjbGVhciBwYXR0ZXJuIGlzIGZvdW5kIGZvciBwZW9wbGUgd2hvIGhhcyBlZHVjYXRpb24gb2YgaGlnaCBzY2hvb2wgb3IgbGVzcy4NClR3byBjbGlja2JhaXR5IHJlc3VsdHMgYXJlIGZvdW5kIGluIHBsb3Q0YiBhbmQgNGMuIFBsb3Q0YiBleHBsb3JlcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIGF2ZXJhZ2UgZm9vZCBjb3N0IChpbmNsdWRpbmcgdG90YWwgYW1vdW50IHNwZW50IG9uIGZvb2QgYXQgaG9tZSwgZm9yIGRlbGl2ZXJ5LCBhbmQgYXdheSBmcm9tIGhvbWUpIC0gaW5jb21lIHJhdGlvIGFuZCBiYW5rcnVwdGN5LiBQZW9wbGUgd2hvIGV4cGVyaWVuY2VkIGJhbmtydXB0Y3kgaGFzIGEgaGlnaGVyIHJhdGlvIG9mIGZvb2QgY29zdCBhbmQgaW5jb21lIHRoYW4gdGhvc2Ugd2hvIGRpZCBub3QgZXhwZXJpZW5jZSBiYW5rcnVwdGN5LCB3aGljaCBjb3VsZCBiZSBpbnRlcnByZXRlZCBhcyBwZW9wbGUgd2hvIHNwZW50IG1vcmUgcHJvcG9ydGlvbiBvZiBtb25leSBvbiBmb29kIGFyZSBtb3JlIGxpa2VseSB0byBleHBlcmllbmNlIGJhbmtydXB0Y3kuDQpQbG90NGMgc2hvd3MgYSBjb21wbGV0ZWx5IGRpZmZlcmVudCBwYXR0ZXJuLiBUaG9zZSB3aG8gaGF2ZSBhIGhpZ2hlciBmb29kIGNvc3QgLSBhc3NldCByYXRpbyBhcmUgbGVzcyBsaWtlbHkgdG8gaGF2ZSBiYW5rcnVwdGN5IGFuZCB0aGVpciByYXRpbyBpcyBtdWNoIGhpZ2hlciB0aGFuIHRoZWlyIGNvdW50ZXJwYXJ0cyB3aG8gYXJlIGJhbmtydXB0ZWQuIEl0IGNvdWxkIGhhdmUgYSBtaXNsZWFkaW5nIGluZmx1ZW5jZSBhbmQgdW5pbnRlbmRlZCBwb3NpdGl2ZSBlZmZlY3Qgb24gZm9vZCBhZHZlcnRpc2VtZW50LCB3aGljaCBzaG93cyB0aGF0IHNwZW5kaW5nIG1vcmUgb24gZm9vZCBtYWtlcyB5b3UgbGVzcyBsaWtlbHkgdG8gYmUgYmFua3J1cHRlZC4NCg0KDQojIDUuIE1ha2UgdHdvIHBsb3RzIGludGVyYWN0aXZlDQojIyBhLiANCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0KKGdncGxvdGx5KHBsb3QxYikpDQpgYGANCg0KDQpBZGRpbmcgaW50ZXJhY3Rpdml0eSB0byB0aGlzIHBsb3QgZW5hYmxlcyByZWFkZXJzIHRvIGtub3cgdGhlIGRldGFpbCBvZiB0aGlzIHBsb3QsIGxpa2Ugc2hvd2luZyB0aGUgYW1vdW50IG9mIHN0dWRlbnQgbG9hbiBhbmQgaG91c2Vob2xkIGRlYnQsIHdoaWNoIGNvbXBlbnNhdGVzIGZvciB0aGUgYW1iaWd1aXR5IG9mIHRoZSBkaWZmZXJlbmNlcyBhbW9uZyB0aGUgY29sb3JzLg0KDQoNCiMjIGIuIA0KYGBge3IsIHdhcm5pbmc9RkFMU0V9DQpzY2ZiZiA8LSBTQ0YgJT4lIA0KICBzZWxlY3QoWUVBUiwgRUROX0lOU1QsIERFQlQsIEVEQ0wsIEJOS1JVUExBU1Q1LCBGT1JFQ0xMQVNUNSkgJT4lIA0KICBmaWx0ZXIoRUROX0lOU1QgPiAwLCBERUJUID4gMCkgJT4lIA0KICBmaWx0ZXIoQk5LUlVQTEFTVDUgPT0gIlllcyIgfCBGT1JFQ0xMQVNUNSA9PSAxKSAlPiUgDQogIGdyb3VwX2J5KFlFQVIsIEVEQ0wpICU+JSANCiAgc3VtbWFyaXNlKGVkdWJmID0gcm91bmQobWVhbihFRE5fSU5TVCAvIERFQlQpLCAyKSkNCg0KcGxvdDViIDwtIGdncGxvdChzY2ZiZiwgYWVzKHggPSBZRUFSLCB5ID0gZWR1YmYsIGNvbG9yID0gRURDTCkpICsNCiAgZ2VvbV9saW5lKHNpemUgPSAxKSArDQogIHlsYWIoIlN0dWRlbnQgTG9hbiAtIERlYnQgUmF0aW8iKSArDQogIHhsYWIoIlllYXIiKSArDQogIGZhY2V0X3dyYXAoRURDTCB+IC4pICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzY2ZiZiRZRUFSKQ0KDQpwbG90NWIgPC0gZ2dwbG90bHkocGxvdDViKQ0KDQpwbG90NWJbWyd4J11dW1snbGF5b3V0J11dW1snYW5ub3RhdGlvbnMnXV1bWzFdXVtbJ3knXV0gPC0gLTAuMDYNCnBsb3Q1YltbJ3gnXV1bWydsYXlvdXQnXV1bWydhbm5vdGF0aW9ucyddXVtbMl1dW1sneCddXSA8LSAtMC4wNg0KDQpwbG90NWINCmBgYA0KDQoNCkFkZGluZyBpbnRlcmFjdGl2aXR5IHRvIHRoaXMgcGxvdCBlbmFibGVzIHJlYWRlcnMgdG8ga25vdyB0aGUgZXhhY3Qgc3R1ZGVudCBsb2FuIC0gZGVidCByYXRpbyBvZiBlYWNoIHllYXIgZm9yIGRpZmZlcmVudCBlZHVjYXRpb24gbGV2ZWxzLiBJdCBtYWtlcyB0aGUgcGxvdCBtb3JlIGluZm9ybWF0aXZlIGFuZCBpbnRlcmFjdGl2ZS4NCg0KDQojIDYuIERhdGEgVGFibGUNCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0Kc2NmYmYgPC0gU0NGICU+JSANCiAgc2VsZWN0KFlFQVIsIEJOS1JVUExBU1Q1LCBGT1JFQ0xMQVNUNSwgRk9PRERFTFYsIEZPT0RBV0FZLCBERUJULCBSQUNFKSAlPiUgDQogIGZpbHRlcihZRUFSID4gMjAwMywgREVCVCA+IDApICU+JSANCiAgZ3JvdXBfYnkoWUVBUiwgQk5LUlVQTEFTVDUsIFJBQ0UpICU+JSANCiAgc3VtbWFyaXNlKGRlbCA9IHJvdW5kKG1lYW4oRk9PRERFTFYvREVCVCksIDMpKSAlPiUgDQogIGZpbHRlcihkZWwgPiAwKQ0KDQpkYXRhdGFibGUoc2NmYmYsIGNvbG5hbWVzID0gYygiWWVhciIsICJCYW5rcnVwdGN5IiwgIlJhY2UiLCAiRm9vZCBEZWxpdmVyeSB0byBEZWJ0IFJhdGlvIiksIA0KICAgICAgICAgIGZpbHRlciA9IGxpc3QocG9zaXRpb24gPSAidG9wIikpDQpgYGANCg0KDQpUaGlzIHRhYmxlIGlzIGEgc3Vic2V0IG9mIHRoZSBkYXRhc2V0LiBJdCBzaG93cyB0aGUgYW1vdW50IHNwZW50IG9uIGZvb2QgZGVsaXZlcnkgYW5kIHRvdGFsIGRlYnQgcmF0aW8gYW1vbmcgZGlmZmVyZW50IHJhY2UgZ3JvdXBzIGFuZCBiYW5rcnVwdGN5IHN0YXR1cy4gSXQgaW5jbHVkZXMgc3VjaCBpbmZvcm1hdGlvbiBmcm9tIGFsbCBhdmFpYWJsZSB5ZWFycyBmcm9tIDIwMDQgdG8gMjAxNi4gVGhlIGNvbHVtbnMgYXJlIHdlbGwgbGFiZWxlZC4gVGhpcyB0YWJsZSBpcyBoZWxwZnVsIGZvciByZWFkZXJzIHRvIGxlYXJuIGFib3V0IHRoZSAiZXh0cmF2YWdhbnQiIGZvb2QgY29uc3VtcHRpb24gYmVoYXZpb3JzLCBmb29kIGRlbGl2ZXJ5LCBzcGVjaWZpY2FsbHkuIFRoZSByYXRpbyBvZmZlcnMgY29tcGFyaXNvbiB3aXRoIGRlYnQsIHdoaWNoIGNvdWxkIGJlIHBvdGVudGlhbGx5IGVkdWNhdGlvbmFsIHRvIHBlb3BsZSB3aG8gYXJlIGludGVyZXN0ZWQgaW4gY2hhbmdpbmcgdGhlaXIgZm9vZCBjb25zdW1wdGlvbiBiZWhhdmlvcnMuDQoNCg==